//
//  ImageViewExtention.swift
//  SwiftLearning
//
//  Created by 黄龙 on 2023/12/13.
//

import Foundation
import UIKit
import SDWebImageWebPCoder

extension UIImageView{
    func imageWithDef(_ defName:String?){
        if defName != nil{
            self.imageWithUrl(defName!)
        }
    }
    
    func imageWithUrl(_ imgurl:String,defName:String?=nil){
//imgurl可以为资源图片名、url、filepath等
        if imgurl.isEmpty{
            self.imageWithDef(defName)
            return
        }
        
        let lowUrl = imgurl.lowercased()
//线上图片文件
        if lowUrl.hasPrefix("http"){
            self.loadImageFrom(imageUrl: imgurl) { picUrl in
                if picUrl == nil {
                    self.imageWithDef(defName)
                }
            }
        }
//线下图片文件
        else if lowUrl.hasSuffix(".webp"){
            guard let path = Bundle.main.path(forResource: imgurl, ofType: "") else {
//得到资源路径： /private/var/containers/Bundle/Application/8B0747A7-92AD-4838-835D-3CCE5F1F39EE/HLDesktop.app/xxx.webp
                self.imageWithDef(defName)
                return
            }
            let webpData = NSData(contentsOfFile: path)
            if let webpImage = UIImage.sd_image(with: webpData as? Data){//引用的是SDWebImage中的UIImage+MultiFormat
//sd_imageWithData！！！在iOS13上webp显示失败,因为从SDWebImage 5.0版本开始，我们将WebP支持代码和libwebp从Core Repo移到了这个独立的SDWebImageWebPCoder中，
//但在iOS16上却是可以的，这是因为苹果的ImageIO支持iOS 14/tvOS 14/watchOS 7/macOS 11的WebP解码，因此这些平台上的SDWebImage也可以解码WebP图像
//在iOS13上sd_imageWithData会返回为nil,应该使用SDImageWebPCoder的sd_imagewithWebPData
                self.image = webpImage
            }else if let ios13_webP = UIImage.sd_image(withWebPData: webpData as? Data){ //引用的是"UIImage+WebP.h"中的SDImageWebPCoder
                self.image = ios13_webP //实测OK，可以支持iOS13上显示webP
            }else{
                self.imageWithDef(defName)
            }
        }else if lowUrl.hasSuffix(".gif"){
            self.imageWithDef(defName) //先加载为默认图片
            self.startGifWithFilePath(filePath: imgurl)
        }else if lowUrl.hasSuffix(".png") || lowUrl.hasSuffix(".jpg") || lowUrl.hasSuffix(".jpeg"){
            self.image = UIImage(named: imgurl)
        }else{
            self.image = UIImage(named:imgurl) //Assets中的图片，如：UIImage(named:"owl-login")
        }
        
    }
    
//加载系统SF图标
    func imageWithSF(sfname:String,foreColor:UIColor?=nil,backColor:UIColor?=nil){
        if foreColor != nil{
            self.image = UIImage(systemName: sfname)?.withTintColor(foreColor!,renderingMode: .alwaysOriginal)
        }else{//以secondaryLabel为默认前景色
            self.image = UIImage(systemName: sfname)?.withTintColor(.secondaryLabel,renderingMode: .alwaysOriginal)
        }
        if backColor != nil{
            self.backgroundColor = backColor
        }
    }
    
    //异步加载网络图片,seccondUrl备用网络地址
    typealias os_block_string = (_ picUrl:String?) -> Void
    func loadImageFrom(imageUrl : String,And seccondUrl:String?=nil,CompleteBlock:os_block_string?=nil){
        guard let urlPath = URL(string: imageUrl) else {
            print("loadImageFrom: Source for the url error")
            CompleteBlock?(nil)//表示加载图片出错
            return
        }
        //sd_setImageWithUrl本身已有缓存机制
        //Option:SDWebImageContinueInBackground后台下载,如果用了，会返回多次,image=nil,但其实并不是url有问题
        self.sd_setImage(with: urlPath, placeholderImage: nil) { [weak self](image, error, cacheType, url) in
            if error != nil || image == nil{
                if let strBkUrl = seccondUrl{
                    self?.loadImageFrom(imageUrl: strBkUrl,And: nil,CompleteBlock: CompleteBlock)
                }else{
                    CompleteBlock?(nil) //表示加载图片出错
                }
            }else{
                CompleteBlock?(urlPath.absoluteString)
            }
        }
    }
    
    public func startGifWithFilePath(filePath:String) {
        if filePath.lowercased().hasPrefix("file://"){
//相册文件路径等:file:///private/var/mobile/Containers/Data/Application/xxx/tmp/BD2C7064-6403-444F-9CFA-5BEC85751195.gif
            if let imgUrl = URL(string: filePath){
                if let imgData = NSData(contentsOf: imgUrl){//当相册刚刚被访问过，此时是可以获取相册图片数据的
                    self.image = UIImage.sd_image(withGIFData: imgData as Data)
                }
            }
        }else{
            guard let path = Bundle.main.path(forResource: filePath, ofType: "") else {
                print("SwiftGif: Source for the image does not exist")
                return
            }
//得到本地资源路径： /private/var/containers/Bundle/Application/8B0747A7-92AD-4838-835D-3CCE5F1F39EE/HLDesktop.app/belowsea.gif
            if let imgData = NSData(contentsOfFile: path){ //本地资源文件路径不能转成URL读取
                self.image = UIImage.sd_image(withGIFData: imgData as Data)
            }
        }
    }
    
}

extension UIImageView{
//MARK: - 将view分裂成指定大小的碎片，然后下跌UIView.animate位移动画
    func animateImageToCrush(crushSize:CGSize,xSmall:CGFloat = -10.0,xBig:CGFloat=10.0, duration:TimeInterval=0.5,delayTime:TimeInterval=0.25) {
        if self.image == nil{
            self.removeFromSuperview()
            return
        }
        let sourceImage = self.image!
        let tmpView = UIView(frame: self.frame) //创建一个相同位置的在前面放置撕碎的碎片
        self.superview?.insertSubview(tmpView, aboveSubview: self)
        tmpView.clipsToBounds = true
        
        var snapshots:[UIImageView] = []
        for x in stride(from: CGFloat(0), through: self.bounds.width, by: crushSize.width) {
            for y in stride(from: CGFloat(0), to: self.bounds.height, by: crushSize.height) {
                let snapshotRegion = CGRect(origin: CGPoint(x: x, y: y), size: crushSize)
//                if let strideImage = self.snapshot2Image(with: snapshotRegion){
                    //撕成小碎片并绘制到临时tmpImgView上;效率低，不适合将大的图像，撕成很小的区块；而且如果碎片过多，会造成崩溃;
                if let strideImage = SwiftFunc.copyImageFrom(Big: sourceImage, at: snapshotRegion){ //改用这个，从源image中直接copy指定区域
                    let tmpImgView = UIImageView(frame: snapshotRegion)
                    tmpView.addSubview(tmpImgView)
                    tmpImgView.image = strideImage
//                    tmpImgView.layer.borderWidth = 0.25 //test.标识是否碎裂成功
//                    tmpImgView.layer.borderColor = UIColor.yellow.cgColor
                    snapshots.append(tmpImgView)
                }
            }
        }
//先将本身移除
        self.removeFromSuperview()
//然后将碎片下跌并移除
        UIView.animate(
            withDuration:
                0.15,
            delay: 0,
            options: UIView.AnimationOptions.curveLinear,
            animations: {
                for perView in snapshots {
                    let xOffset = SwiftFunc.randomFloatBetween(xSmall , and: xBig)
                    let yOffset = SwiftFunc.randomFloatBetween(xSmall , and: xBig)
                    perView.frame = perView.frame.offsetBy(dx: CGFloat(xOffset), dy: CGFloat(yOffset)) //先打碎
                }
            },
            completion: { _ in
                //usingSpringWithDamping传入数值为0.0~1.0,数值越大,弹性越不明显
                //initialSpringVelocity数值越大，初始速度越大
                UIView.animate(withDuration: duration, delay:delayTime, usingSpringWithDamping: 0.75, initialSpringVelocity: 0.15, options: [.curveEaseInOut]) {
                    for perView in snapshots {
                        let xOffset = 0.0 //垂直落下， //SwiftFunc.randomFloatBetween(xSmall , and: xBig) //飘落
                        let yOffset = SwiftFunc.randomFloatBetween(tmpView.frame.height-crushSize.height, and: tmpView.frame.height-2*crushSize.height)
                        perView.frame = perView.frame.offsetBy(dx: xOffset, dy: CGFloat(yOffset)) //然后下跌
                    }
                }completion: { _ in
                    for perView in snapshots {
                        perView.removeFromSuperview()
                    }
                    tmpView.removeFromSuperview() //移除临时view
                }
                
            }
        )
    }
}
